﻿// Copyright (c) 2012 - 2021 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2021-03-19 version 4.0.0 Jared Zheng <jaredz at outlook dot com>

#ifndef __SERVER_SORT_H__
#define __SERVER_SORT_H__

#pragma once

#include "CommonDefine.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务信息排序常量定义
enum SORT_DEFAULT_ENUM
{
    SORTD_GROW  = 128,  // 同步是最多选取最前面的SORTD_GROW
    SORTD_COUNT = 1024, // 排序结果保存默认数量
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务信息排序结构定义
struct tagSERVER_NODE : public MObject
{
public:
    tagSERVER_NODE(void)
    : ullKey(0)
    , usLoad(0)
    , usRate(0)
    , usId(0)
    , usData(0)
    {
    }

    ~tagSERVER_NODE(void)
    {
    }

    size_t Length(void) const
    {
        return (sizeof(ULLong) + sizeof(UShort) + sizeof(UShort) + sizeof(UShort) + sizeof(UShort) + Addr.Length());
    }

    void Serialize(CStream& Stream)
    {
        if (Stream.IsRead())
        {
            Stream >> ullKey >> usLoad >> usRate >> usId >> usData;
        }
        else
        {
            Stream << ullKey << usLoad << usRate << usId << usData;
        }
        Addr.Serialize(Stream);
    }
public:
    ULLong     ullKey;   // session key
    UShort     usLoad;   // 服务负载情况(万分比)
    UShort     usRate;   // 服务负载变化比率(万分比)
    UShort     usId;     // 服务Id
    UShort     usData;   // 保留数据
    CStrAddr   Addr;     // 地址信息
};
typedef struct tagSERVER_NODE   SERVER_NODE, *PSERVER_NODE;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 快速排序服务负载
struct tagQUICK_SORT : public tagSERVER_NODE
{
public:
    static void QuickSort(tagSERVER_NODE* pNode, Int nCount);
    static void QuickSortRecursion(tagSERVER_NODE* pNode, Int nBegin, Int nEnd);
    static Int  Partition(tagSERVER_NODE* pNode, Int nBegin, Int nEnd);
public:
    tagQUICK_SORT(void);
    ~tagQUICK_SORT(void);
};
typedef struct tagQUICK_SORT   QUICK_SORT, *PQUICK_SORT;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务按负载情况排序数组
struct tagSORT_RESULT : public MObject
{
public:
    tagSORT_RESULT(void);
    ~tagSORT_RESULT(void);
    // 重置数据
    void   Reset(void);
    void   Count(UInt uAddCount);
    // 获取排序结果最小负载的服务索引号
    UInt   Index(void);
    UInt   Find(ULLong ullKey);
    // 获取排序结果最大负载
    UShort MaxLoad(void);
public:
    UInt                  uIndex; // 最后更新的索引号
    UInt                  uCount; // 排序结果总数
    CTArray<QUICK_SORT>   Sort;   // 排序结果数组
};
typedef struct tagSORT_RESULT   SORT_RESULT, *PSORT_RESULT;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 服务按负载情况排序数组交换链
struct tagSORT_CHAIN : public MObject
{
public:
    tagSORT_CHAIN(void);
    ~tagSORT_CHAIN(void);
    // 重置数据
    void Reset(void);
    // 切换数组
    void Swap(void);
    // 获取当前使用的数组
    SORT_RESULT& GetCur(void);
    // 获取后备数组
    SORT_RESULT& GetNext(void);
public:
    UInt          uIndex;    // 当前使用的数组索引号
    SORT_RESULT   Result[2]; // 交换数组
};
typedef struct tagSORT_CHAIN   SORT_CHAIN, *PSORT_CHAIN;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "ServerSort.inl"

#endif // __SERVER_SORT_H__
